Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional group theory functions for error correction #351

Merged
merged 87 commits into from
Oct 25, 2024

Conversation

IsaacP1234
Copy link
Contributor

Adding logical_operator_canonicalize, commutavise, and embed functions, as well as SubsystemCodeTableau datastructure and minor performance improvements for groupify and normalizer.

@IsaacP1234
Copy link
Contributor Author

@KDGoodenough I have rewritten the documentation for canonicalize noncomm, commutify, and matroid_parent to be more clear, but is there anything about the functions or the theory behind them that I should include in the documentation?

@IsaacP1234
Copy link
Contributor Author

I think I have completed all the requested changes, but I am not aware of more uses of commutify aside from matroid parent to add to its documentation. @KDGoodenough are there any I should add?

Additionally, should I add the newly-referenced papers to references.md?

@KDGoodenough
Copy link
Contributor

@IsaacP1234 I think it's good like this! There's not too much work (yet!) that uses this commutify business. My guess would be that yes, it would be good to add these references to the .md file as well, but Stefan would know better.

@IsaacP1234
Copy link
Contributor Author

Changelog:

  • New error correction tools:
    • canonicalize_noncomm function to find a generating set with minimal anticommutivity
    • SubsystemCodeTableau data structure to represent the output of canonicalize_noncomm
    • commutify function to find a commutative version of a non-commutative set of Paulis with
      minimal changes
    • matroid_parent function to, for set of Paulis that doesn't represent a state, find a version
      that does.

Copy link
Member

@Krastanov Krastanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally got around to reviewing this. Thank you for all these additions and apologies for the long delay.

First, I made a few changes myself, but either github is having its usual reliability problems or you have set some security features a bit higher and I can not push to your branch.

Before you continue, could you please make sure that you pull the changes from this branch: https://github.com/QuantumSavory/QuantumClifford.jl/tree/loc-comm-embed

I tried to make each commit small and self-explanatory -- please check the commits I have added one-by-one to see why they were added.

m::Int
k::Int
end
function SubsystemCodeTableau(t::Tableau)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this constructor necessary? It is a pretty expensive one. Should this not be a part of the canonicalize_noncomm function itself.

end


Base.copy(t::SubsystemCodeTableau) = SubsystemCodeTableau(copy(t.tab))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very expensive way to make a copy as you are redoing a ton of computation. It would be better if this just copies over the various indices as well.

for i in 0:2^n-1
for (digit_order, j) in enumerate(digits(i, base=2, pad=n))
if j == 1
group[i+1] *= s[digit_order]
group[i+1] *= gen_set[digit_order]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mul_left!(group, gen_set, i+1, digit_order) would be drastically faster (it will be in-place, avoiding a lot of allocations).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, does this function work correctly if there are terms with non-trivial phases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are non-real phases it doesn't work because it uses minimal_generating_set which only accepts real phases. Should I rework it to work with imaginary phases or specify in the docs that it only accepts real phases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, there doesn't seem to be any method of mul_left! that can multiply a single row of a Tableau or Stabilizer by a Pauli. Just indexing doesn't change the original structure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just writing down what we discussed in the call: just add a kwargument phases=false, and throw an error if someone tries to run phases=true with some message about it not being implemented

For mul_left! could you please just add a new method for it, basically just making a second more general version of this one in the same file

@inline function mul_left!(s::Tableau, m, i; phases::Val{B}=Val(true)) where B

I think it would be just

@inline function mul_left!(s::Tableau, m, t::Tableau, i; phases::Val{B}=Val(true)) where B
    extra_phase = mul_left!((@view s.xzs[:,m]), (@view t.xzs[:,i]); phases=phases)
    B && (s.phases[m] = (extra_phase+s.phases[m]+s.phases[i])&0x3)
    s
end

and then do tab(stabilizer) wherever you call it

julia> tab(logical_operator_canonicalize(QuantumClifford.Tableau([P"XX", P"XZ", P"XY"])))
+ Z_
+ XX
-iX_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, let's just remove the phases

for k in eachindex(t)
if k !=i && k != j
if comm(t[k], t[i]) == 0x01
t[k] = t[j] *t[k]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mul_left!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with phases=false

loc[index]= t[i]
index+=1
end
if !(t[j] in loc || -1 *t[j] in loc || 1im *t[j] in loc || -1im * t[j] in loc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment about cost of check

while length(loc) > 1 && loc[length(loc)-1] == zero(PauliOperator, nqubits(loc))
loc = loc[1:(length(loc)-1)]
end
return SubsystemCodeTableau(loc)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give the constructor more information so it does not run all that expensive processing and searching?

puttableau!(commutative, x, i, nqubits(loc)+i)
puttableau!(commutative, z, i+loc.r+loc.k, nqubits(loc)+i)
end
to_delete = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something more like nqubits+1:nqubits+k would be much simpler and faster

+ ZZZ

julia> matroid_parent(T"XX")[2]
1-element Vector{Any}:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be ranges or vectors of ints, not vectors of any

3

julia> matroid_parent(T"XX")[3]
Any[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should be ranges or vectors of ints, not vectors of any

@Krastanov
Copy link
Member

by the way, to verify my claims about speed, you can use BenchmarkTools and the @benchmark macro

@IsaacP1234
Copy link
Contributor Author

All requested chnages complete. For the SubsystemCodeTableau constructor, I now format the Tableau in canonicalize_noncomm, but I left the expensive one in in case a Tableau generated from another function needs to be stored as a SubsystemCodeTableau

@IsaacP1234 IsaacP1234 requested a review from Krastanov October 3, 2024 01:23
Copy link

codecov bot commented Oct 25, 2024

Codecov Report

Attention: Patch coverage is 67.24138% with 57 lines in your changes missing coverage. Please review.

Project coverage is 82.53%. Comparing base (0849b1c) to head (8f14bd3).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/grouptableaux.jl 66.27% 57 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #351      +/-   ##
==========================================
- Coverage   83.11%   82.53%   -0.59%     
==========================================
  Files          70       70              
  Lines        4418     4580     +162     
==========================================
+ Hits         3672     3780     +108     
- Misses        746      800      +54     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Krastanov Krastanov merged commit f3eb7cd into QuantumSavory:master Oct 25, 2024
14 of 16 checks passed
@Krastanov
Copy link
Member

Finally merged! Thanks so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants